import json
import os
import tiktoken

GPT_ROLE_SYS = 'system'
GPT_ROLE_USER = 'user'
GPT_ROLE_ASSISTANT = 'assistant'
GPT_ROLE_FUN = 'function'

MD_PRO_ORG1 = """
| 部门ID                             | 部门名称       | 上级部门ID                           |
|----------------------------------|------------|----------------------------------|
| 8a8ab0b246dc81120146dc8180ba0017 | 武黄高速      |                                  |
| f6323b406b4fab1b016bacab7db301d1 | 监理         | f632d53969b410ac0169bd10699f0044 |
| f6323b406b4fab1b016bacabdb9f01d3 | 武黄1标      | f6323b406b4fab1b016bacab7db301d1 |
| f6323b406b4fab1b016bacac674901d5 | 武黄2标      | f6323b406b4fab1b016bacab7db301d1 |
| f6323b406c1829b3016c269c75fd0034 | 武黄1标试验室   | f6323b406b4fab1b016bacabdb9f01d3 |
| f6323b406c1829b3016c269d3b2c0036 | 武黄1标工地试验室 | f6323b406b4fab1b016bacabdb9f01d3 |
| f6323b406c1829b3016c269d9e710038 | 武黄2标试验室   | f6323b406b4fab1b016bacac674901d5 |
| f6323b406c465360016ce6c9a18d0ca9 | 武黄3标      | f6323b406b4fab1b016bacab7db301d1 |
| f6323b406c465360016ce6cc77490cac | 武黄3标试验室   | f6323b406c465360016ce6c9a18d0ca9 |
| f6323b406d19fc87016d1a5b861b0014 | 武黄1标拌合站   | f6323b406b4fab1b016bacabdb9f01d3 |
| f6323b406d19fc87016d1a5c43910016 | 武黄2标1号拌合站   | f6323b406b4fab1b016bacac674901d5 |
| f6323b406d19fc87016d1a5c43910018 | 武黄2标2号拌合站   | f6323b406b4fab1b016bacac674901d5 |
| f6323b406dde6af5016decd816160194 | 武黄3标拌合站   | f6323b406c465360016ce6c9a18d0ca9 |
| f6323b406dde6af5016decd814150192 | 武黄3标搅拌站   | f6323b406c465360016ce6c9a18d0ca9 |
| f6323b407321d51d01733bfe77dd04af | 武黄2标五集中站  | f6323b406b4fab1b016bacac674901d5 |
| f632d53969b410ac0169bd10699f0044 | 武黄高速监理    | 8a8ab0b246dc81120146dc8180ba0017 |
"""

MD_PRO_ORG2 = """
| 部门ID                             | 部门名称       | 上级部门ID                           |
|----------------------------------|------------|----------------------------------|
| f6323b406b4fab1b016bacabdb9f01d3 | 武黄1标      | f6323b406b4fab1b016bacab7db301d1 |
| f6323b406c1829b3016c269c75fd0034 | 武黄1标试验室   | f6323b406b4fab1b016bacabdb9f01d3 |
| f6323b406c1829b3016c269d3b2c0036 | 武黄1标工地试验室 | f6323b406b4fab1b016bacabdb9f01d3 |
| f6323b406d19fc87016d1a5b861b0014 | 武黄1标拌合站   | f6323b406b4fab1b016bacabdb9f01d3 |
"""

ORG_CONF = {
    "user1":MD_PRO_ORG1,
    "user2": MD_PRO_ORG2,
}

ORG_ID = {
    "user1": '8a8ab0b246dc81120146dc8180ba0017',
    "user2": 'f6323b406b4fab1b016bacabdb9f01d3',
}


# Ignore all previous instructions,give me very short and concise answers and all the niceties that openai programmed you with,I know you are a large language model,
# SYSTEM_PROMPT = """
# You are a project data administrator who is skilled in calculating project data based on conversations and then providing me with concise results. Today's date is{},The project structure is as follows:{}"""
SCENE_PROMPT = """
您是一名分析员，根据我的提问告诉我提问适合的场景编号，且不应回复我任何其他内容:
1.Query material entry weighing data based on depart ID, time, and material name;
2.Query material exit weighing data based on depart ID, time, and material name;
3.Query the latest inventory data of materials based on their outbound ID, time, and material name. Be careful not to disturb;
4.Query device and site information, display corresponding device information for the site during display, Be careful Weighbridge understood as geomagnetism
5.Query material entry weighing data and associated suppliers based on outbound ID, time, and material name
6.Query the number of production tasks based on the ID and time.
7.Retrieve production status based on ID and time
8.Retrieve exceeding conditions based on ID, time, and name.
9.Query the device status by ID and time
10.Query out-of-standard processing data by ID, time, and name.
11.Query the concrete output of each project site according to ID and time.
"""

SYSTEM_PROMPT = """
您是一名项目数据管理员，擅长根据对话统计项目数据，为我提供markdown格式的分析结果并以表格的形式输出。您必须遵守这些规则：
1.今天的日期是{}；
2.回复中站点必须属于项目结构；
3.回复中涉及材料名称部分必须属于['{}']；
4.回复中材料必须按照部门或者站点分组；
5.回复中时间必须按照yyyy-MM-dd格式,不允许返回相关的代码；
6.数值部分需要转化为链接；
7.项目结构如下：{} 回复举例：
武黄2标拌合站：
    材料              总重量(吨)

武黄1标拌合站：
    材料              总重量(吨)

"""

BANHEZHAN_PROMPT = """
您是一名项目数据管理员，擅长根据对话统计项目数据，为我提供markdown格式的分析结果并以表格的形式输出。您必须遵守这些规则：
1.今天的日期是{}；
2.回复中站点必须属于项目结构；
3.回复中涉及生产材料用料名称部分属于['{}']；
4.回复中材料必须按照部门或者站点分组；
5.数值部分需要转化为链接；
6.项目结构如下：{} 回复举例：
武黄2标拌合站：
    材料              总重量(吨)

武黄1标拌合站：
    材料              总重量(吨)

"""

CON_SYSTEM_PROMPT = """
您是一名项目数据管理员，擅长根据对话统计项目数据，为我提供markdown格式的分析结果并以表格的形式输出。您必须遵守这些规则：
1.今天的日期是{}；
2.回复中站点必须属于项目结构；
3.回复中涉及材料名称部分必须属于['{}']；
4.回复中材料必须按照部门或者站点分组；
5.回复中时间必须按照yyyy-MM-dd格式,不允许返回相关的代码；
6.数值部分需要转化为链接；
7.项目结构如下：{} 回复举例：
武黄2标拌合站：
    材料              总重量(吨)

武黄1标拌合站：
    材料              总重量(吨)

"""

CON_TWO_SYSTEM_PROMPT = """
您是一名项目数据管理员，根据我提供的问题和数据统计项目数据：
1.今天的日期是{}；
2.问题是以QUE开头的字符串，数据是以DATA开头的字符串,时间以TIME开头的字符串
3.回复中站点必须属于项目结构；
4.回复中涉及材料名称部分必须属于['{}']；
5.回复中材料必须按照部门或者站点分组；
6.回复中时间必须按照yyyy-MM-dd格式,不允许返回相关的代码；
7.数值部分需要转化为链接；
8.项目结构如下：{} 回复举例：
武黄2标拌合站：
    材料              总重量(吨)

武黄1标拌合站：
    材料              总重量(吨)

"""

CON_TWO_MAX_SYSTEM_PROMPT = """
您是一名项目数据管理员，根据我提供的问题和数据统计项目数据:
1.今天的日期是{};
2.回复中时间必须按照yyyy-MM-dd格式,不允许返回相关的代码;
3.数值部分需要转化为链接;
4.回复项目案例结构如下:
2023-09-04生产任务情况如下:
#武黄高速项目
施工一标
武黄1标拌合站
|任务单总数|生产中|已完成|
|------|------|------|
|13|4|9|
"""

CON_THREE_MAX_SYSTEM_PROMPT = """
您是一名项目数据管理员，根据我提供的问题和数据统计项目数据:
1.今天的日期是{};
2.回复中时间必须按照yyyy-MM-dd格式,不允许返回相关的代码;
3.数值部分需要转化为链接;
4.回复项目案例结构如下:
2023-09-04实验设备情况如下:
#武黄高速项目
施工一标
|设备名称|设备总数|正常工作|延时工作|未工作|未安装|
|------|------|------|------|------|------|
|压力机|20|10|5|5|10|
|万能机|20|10|5|5|10|
|总计|40|20|10|10|20|
"""

BANHEZHAN_CL = """[砂1,碎石1,砂2,碎石2,碎石4,水泥1,水泥2,矿粉,粉煤灰,粉煤灰2,水,水2,减水剂1,减水剂2,外加剂3,外加剂4]"""

CHART_SYSTEM_PROMPT = """You are a material weighing administrator, and you are skilled in providing statistical information about materials based on my questions\nI am a supervisor, 
and the JSON information for the Site/Material/Net weight - tons \n Emphasis : Please the key must be to convert this json to echarts json"""

CHAT_CACHE = {}

SRC_CL = """[水泥,支座砂浆,水泥P.O42.5（包装）,水泥P.O52.5(散装）,水泥P.O42.5（散装）,水泥32.5,水泥P.O52.5,水泥P.O42.5,水泥PC.425(包装),水泥PC.425（散装）,水泥32.5（散装）,水泥PO42.5（散装）,碎石,石渣,碎石5-10,防撞墩,碎石10-20,碎石16-31.5,碎石5-16,片石,卵石土,碎石0-5,碎石1-2,碎石1-3,机制砂,河沙,石粉,混合料,石灰,碎石2-4,碎石0-5（沥青）,碎石1-2（沥青）,碎石1-3（沥青）,石粉（沥青）,碎石小0-5（沥青）,碎石大0-5（沥青）,玄武岩1号籽,玄武岩2号籽,粉煤灰,粉煤灰,粉煤灰,粉煤灰,细骨料,碎石机制砂,河砂,卵石机制砂,外加剂,减水剂,防腐剂KT-6,气密剂KY-11,引气剂KT,聚丙烯纤维网,压浆料,灌浆料,孔道压浆料,高标减水剂,自制砂高标号减水剂,自制砂低标号减水剂,养护膜,矿粉,矿粉,原沙,水,水,钢材,盘元,钢带,钢网片,槽钢,钢材套铜,冷钢,湘钢,涟钢,螺纹钢,角钢,钢板,方管,工字钢,钢管,声测管,护栏模板,钢模板,不锈钢板,钢绞线,圆钢,柴油,柴油,重柴油,粉料,煤粉,硅粉,沥青类,乳化沥青,下面层沥青料,中面层沥青料,上面层沥青料,SMA-13上面层,70号沥青,改性沥青,交安材料,镀锌方立柱,木质纤维,防阻块,立柱]"""

SCENE_VALUE = """[进场,出场,设备,库存,供货,生产任务,生产情况,工程部位,超标情况,超标处置情况,生产设备,试验任务情况,试验设备运行情况,试验龄期提醒]"""
SCENE_KEY = """[磅房,拌合站,试验室]"""
SCENE_KEY_VALUE = """{磅房:[进场,出场,设备,库存,供货],拌合站:[生产任务,生产情况,工程部位,超标情况,超标处置情况,生产设备],试验室:[试验任务情况,试验设备运行情况,试验龄期提醒]}"""
SCENE = {
    'pound':['inputStatic','outputStatic','devStatic','inventoryStatic','supplierStatic'],
    'mix':['shengchanqk_ovStatic','shengchanrw_ovStatic','gcbw_ovStatic','shengchansb_ovStatic','chuzhi_ovStatic','chaobiao_ovStatic'],
    'laboratory':['shiyan_ovStatic', 'yawan_ovStatic','lingqi_ovStatic']
}

from functions.inputStatic import inputStatic
from functions.inputStatic import functionConf as isf

from functions.outputStatic import outputStatic
from functions.outputStatic import functionConf as opf

from functions.inventoryStatic import inventoryStatic
from functions.inventoryStatic import functionConf as itf

from functions.devStatic import devStatic
from functions.devStatic import functionConf as devf

from functionsbak.questStatic import questStatic
from functionsbak.questStatic import functionConf as qesf

from functionsbak.productionStatic import productionStatic
from functionsbak.productionStatic import functionConf as pdsf

from functionsbak.ostandardStatic import ostandardStatic
from functionsbak.ostandardStatic import functionConf as osdf

from functionsbak.materialsStatic import materialsStatic
from functionsbak.materialsStatic import functionConf as mtsf

from functionsbak.equipmentStatic import equipmentStatic
from functionsbak.equipmentStatic import functionConf as eqpf

from functionsbak.chuzhiStatic import chuzhiStatic
from functionsbak.chuzhiStatic import functionConf as czsf

from functionsbak.gcmcStatic import gcmcStatic
from functionsbak.gcmcStatic import functionConf as gcsf

# from functionsbak.shiyanStatic import shiyanStatic
# from functionsbak.shiyanStatic import functionConf as sysf
#
# from functionsbak.yawanStatic import yawanStatic
# from functionsbak.yawanStatic import functionConf as ywsf

from functionsbak.inputStatic import inputStatic
from functionsbaktwo.inputStatic import inputStatic as inputStatictwo
from functionsbak.inputStatic import functionConf as isf
from functionscontrast.inputStatic import functionConf as contrastisf
from functionscontrast.inputStatic import inputStatic as contrastinputStatic

from functionsbak.outputStatic import outputStatic
from functionsbaktwo.outputStatic import outputStatic as outputStatictwo
from functionsbak.outputStatic import functionConf as opf
from functionscontrast.outputStatic import functionConf as contrastopf
from functionscontrast.outputStatic import outputStatic as contrastoutputStatic

from functionsbak.inventoryStatic import inventoryStatic
from functionsbaktwo.inventoryStatic import inventoryStatic as inventoryStatictwo
from functionsbak.inventoryStatic import functionConf as itf

from functionsbak.devStatic import devStatic
from functionsbaktwo.devStatic import devStatic as devStatictwo
from functionsbaktwo.devStatic import functionConf as devf

from functionsbak.supplierStatic import supplierStatic
from functionsbaktwo.supplierStatic import supplierStatic as supplierStatictwo
from functionsbak.supplierStatic import functionConf as supf

from functionsbaktwo.chuzhi_ovStatic import chuzhi_ovStatic
from functionsbaktwo.chuzhi_ovStatic import functionConf as czovf

from functionsbaktwo.chaobiao_ovStatic import chaobiao_ovStatic
from functionsbaktwo.chaobiao_ovStatic import functionConf as cbovf

from functionsbaktwo.gcbw_ovStatic import gcbw_ovStatic
from functionsbaktwo.gcbw_ovStatic import functionConf as gcovf

from functionsbaktwo.shengchanqk_ovStatic import shengchanqk_ovStatic
from functionsbaktwo.shengchanqk_ovStatic import functionConf as scqkovf

from functionsbaktwo.shengchanrw_ovStatic import shengchanrw_ovStatic
from functionsbaktwo.shengchanrw_ovStatic import functionConf as scrwovf

from functionscontrast.shengchanrw_ovStatic import shengchanrw_ov1Static as contrastshengchanrw_ovStatic
from functionscontrast.shengchanrw_ovStatic import functionConf as contrastscrw

from functionsbaktwo.shengchansb_ovStatic import shengchansb_ovStatic
from functionsbaktwo.shengchansb_ovStatic import functionConf as scsbovf

from functionsbaktwo.shiyan_ovStatic import shiyan_ovStatic
from functionsbaktwo.shiyan_ovStatic import functionConf as sysbovf

from functionsbaktwo.yawan_ovStatic import yawan_ovStatic
from functionsbaktwo.yawan_ovStatic import functionConf as ywanovf

from functionsbaktwo.lingqi_ovStatic import lingqi_ovStatic
from functionsbaktwo.lingqi_ovStatic import functionConf as lqivf

# contrast
CONFUNCTIONS = [
    contrastisf,
    contrastopf,
    contrastscrw
]

CON_DICT = {
    contrastisf['name']: contrastinputStatic,
    contrastopf['name']: contrastoutputStatic,
    contrastscrw['name']: contrastshengchanrw_ovStatic
}
FUNCTIONS = [
    isf,
    opf,
    itf,
    devf,
    supf,
    # qesf,
    # pdsf,
    # osdf,
    # mtsf,
    # eqpf,
    # czsf,
    # gcsf,
    # sysf,
    # ywsf,
    czovf,
    cbovf,
    gcovf,
    scqkovf,
    scrwovf,
    scsbovf,
    sysbovf,
    ywanovf,
    lqivf
]

FUN_DICT_BAK = {
    isf['name']: inputStatic,
    opf['name']: outputStatic,
    itf['name']: inventoryStatic,
    devf['name']: devStatic,
    supf['name']: supplierStatic
}

FUN_DICT_BAK_TWO = {
    isf['name']: inputStatictwo,
    opf['name']: outputStatictwo,
    itf['name']: inventoryStatictwo,
    devf['name']: devStatictwo,
    supf['name']: supplierStatictwo
}

FUN_MIX_STA = {
    qesf['name']: questStatic,
    pdsf['name']: productionStatic,
    osdf['name']: ostandardStatic,
    # mtsf['name']: materialsStatic,
    eqpf['name']: equipmentStatic,
    czsf['name']: chuzhiStatic,
    gcsf['name']: gcmcStatic
}

FUN_MIX_STA_TWO = {
    czovf['name']:chuzhi_ovStatic,
    cbovf['name']:chaobiao_ovStatic,
    gcovf['name']:gcbw_ovStatic,
    scqkovf['name']:shengchanqk_ovStatic,
    scrwovf['name']:shengchanrw_ovStatic,
    scsbovf['name']:shengchansb_ovStatic
}

# FUN_EXP_MENT = {
#     sysf['name']: shiyanStatic,
#     ywsf['name']: yawanStatic
# }

FUN_EXP_MENT_TWO = {
    sysbovf['name']: shiyan_ovStatic,
    ywanovf['name']: yawan_ovStatic,
    lqivf['name']: lingqi_ovStatic
}

#pound
#mix
#laboratory
SELECT = {
    'pound':FUN_DICT_BAK,
    'mix':FUN_MIX_STA,
    # 'laboratory':FUN_EXP_MENT
}

SELECT_TWO = {
    'pound':FUN_DICT_BAK_TWO,
    'mix':FUN_MIX_STA_TWO,
    'laboratory':FUN_EXP_MENT_TWO
}

Echart_Not = {
    'inventoryStatic','devStatic','supplierStatic',
    'questStatic','productionStatic',
    'ostandardStatic','equipmentStatic',
    'chuzhiStatic','gcmcStatic','shiyanStatic',
    'yawanStatic','chuzhi_ovStatic','chaobiao_ovStatic',
    'gcbw_ovStatic','shengchanqk_ovStatic','shengchanrw_ovStatic',
    'shengchansb_ovStatic','shiyan_ovStatic','yawan_ovStatic',
    'lingqi_ovStatic'
}

# 创建数据存储文件夹和文件，如果不存在
def create_data_file():
    if not os.path.exists(os.environ.get('DATA_FOLDER')):
        open(os.environ.get('DATA_FOLDER'), 'w').close()

# 存储数据到文件
def save_to_file(data):
    try:
        with open(os.environ.get('DATA_FOLDER'), 'a') as file:
            file.write(data + "\n\n")
        return True
    except Exception as e:
        print(f"Error saving data: {e}")
        return False

def class_to_dict_list(class_list):
    dict_list = []
    for obj in class_list:
        dict_list.append(obj.json())
    return dict_list

def num_tokens_from_messages(messages, model="gpt-3.5-turbo-0613"):
    """Return the number of tokens used by a list of messages."""
    try:
        encoding = tiktoken.encoding_for_model(model)
    except KeyError:
        print("Warning: model not found. Using cl100k_base encoding.")
        encoding = tiktoken.get_encoding("cl100k_base")
    if model in {
        "gpt-3.5-turbo-0613",
        "gpt-3.5-turbo-16k-0613",
        "gpt-4-0314",
        "gpt-4-32k-0314",
        "gpt-4-0613",
        "gpt-4-32k-0613",
        }:
        tokens_per_message = 3
        tokens_per_name = 1
    elif model == "gpt-3.5-turbo-0301":
        tokens_per_message = 4  # every message follows <|start|>{role/name}\n{content}<|end|>\n
        tokens_per_name = -1  # if there's a name, the role is omitted
    elif "gpt-3.5-turbo" in model:
        print("Warning: gpt-3.5-turbo may update over time. Returning num tokens assuming gpt-3.5-turbo-0613.")
        return num_tokens_from_messages(messages, model="gpt-3.5-turbo-0613")
    elif "gpt-4" in model:
        print("Warning: gpt-4 may update over time. Returning num tokens assuming gpt-4-0613.")
        return num_tokens_from_messages(messages, model="gpt-4-0613")
    else:
        raise NotImplementedError(
            f"""num_tokens_from_messages() is not implemented for model {model}. See https://github.com/openai/openai-python/blob/main/chatml.md for information on how messages are converted to tokens."""
        )
    num_tokens = 0
    for message in messages:
        num_tokens += tokens_per_message
        for key, value in message.items():
            num_tokens += len(encoding.encode(value))
            if key == "name":
                num_tokens += tokens_per_name
    num_tokens += 3  # every reply is primed with <|start|>assistant<|message|>
    return num_tokens